"""
基础数据模型类
"""

from datetime import datetime, timezone
from typing import Dict, Any, Optional, List
from bson import ObjectId
import uuid


class BaseModel:
    """基础模型类"""
    
    def __init__(self, collection_name: str):
        """
        初始化基础模型
        
        Args:
            collection_name: MongoDB集合名称
        """
        self.collection_name = collection_name
        self._db = None
    
    @property
    def db(self):
        """获取数据库连接"""
        if self._db is None:
            from .. import get_mongo_db
            self._db = get_mongo_db()
        return self._db
    
    @property
    def collection(self):
        """获取集合对象"""
        return self.db[self.collection_name]
    
    def generate_id(self) -> str:
        """生成唯一ID"""
        return str(uuid.uuid4())
    
    def get_current_time(self) -> datetime:
        """获取当前UTC时间"""
        return datetime.now(timezone.utc)
    
    def to_dict(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """
        转换为字典格式
        
        Args:
            data: 原始数据
            
        Returns:
            Dict: 转换后的字典
        """
        result = {}
        for key, value in data.items():
            if isinstance(value, ObjectId):
                result[key] = str(value)
            elif isinstance(value, datetime):
                result[key] = value.isoformat()
            else:
                result[key] = value
        return result
    
    def create(self, data: Dict[str, Any]) -> str:
        """
        创建新记录
        
        Args:
            data: 记录数据
            
        Returns:
            str: 记录ID
        """
        # 添加创建时间
        data['created_at'] = self.get_current_time()
        data['updated_at'] = self.get_current_time()
        
        # 插入记录
        result = self.collection.insert_one(data)
        return str(result.inserted_id)
    
    def find_by_id(self, record_id: str) -> Optional[Dict[str, Any]]:
        """
        根据ID查找记录
        
        Args:
            record_id: 记录ID
            
        Returns:
            Optional[Dict]: 记录数据或None
        """
        try:
            # 尝试作为ObjectId查找
            if ObjectId.is_valid(record_id):
                record = self.collection.find_one({"_id": ObjectId(record_id)})
            else:
                record = None
            
            if record:
                return self.to_dict(record)
            return None
        except Exception:
            return None
    
    def find_one(self, query: Dict[str, Any]) -> Optional[Dict[str, Any]]:
        """
        查找单个记录
        
        Args:
            query: 查询条件
            
        Returns:
            Optional[Dict]: 记录数据或None
        """
        record = self.collection.find_one(query)
        if record:
            return self.to_dict(record)
        return None
    
    def find_many(self, query: Dict[str, Any] = None, 
                  sort: List[tuple] = None, 
                  limit: int = None, 
                  skip: int = None) -> List[Dict[str, Any]]:
        """
        查找多个记录
        
        Args:
            query: 查询条件
            sort: 排序条件
            limit: 限制数量
            skip: 跳过数量
            
        Returns:
            List[Dict]: 记录列表
        """
        if query is None:
            query = {}
        
        cursor = self.collection.find(query)
        
        if sort:
            cursor = cursor.sort(sort)
        
        if skip:
            cursor = cursor.skip(skip)
        
        if limit:
            cursor = cursor.limit(limit)
        
        return [self.to_dict(record) for record in cursor]
    
    def update_by_id(self, record_id: str, data: Dict[str, Any]) -> bool:
        """
        根据ID更新记录
        
        Args:
            record_id: 记录ID
            data: 更新数据
            
        Returns:
            bool: 是否更新成功
        """
        try:
            # 添加更新时间
            data['updated_at'] = self.get_current_time()
            
            if ObjectId.is_valid(record_id):
                result = self.collection.update_one(
                    {"_id": ObjectId(record_id)},
                    {"$set": data}
                )
                return result.modified_count > 0
            return False
        except Exception:
            return False
    
    def update_one(self, query: Dict[str, Any], data: Dict[str, Any]) -> bool:
        """
        更新单个记录
        
        Args:
            query: 查询条件
            data: 更新数据
            
        Returns:
            bool: 是否更新成功
        """
        # 添加更新时间
        data['updated_at'] = self.get_current_time()
        
        result = self.collection.update_one(query, {"$set": data})
        return result.modified_count > 0
    
    def update_many(self, query: Dict[str, Any], data: Dict[str, Any]) -> int:
        """
        更新多个记录
        
        Args:
            query: 查询条件
            data: 更新数据
            
        Returns:
            int: 更新的记录数量
        """
        # 添加更新时间
        data['updated_at'] = self.get_current_time()
        
        result = self.collection.update_many(query, {"$set": data})
        return result.modified_count
    
    def delete_by_id(self, record_id: str) -> bool:
        """
        根据ID删除记录
        
        Args:
            record_id: 记录ID
            
        Returns:
            bool: 是否删除成功
        """
        try:
            if ObjectId.is_valid(record_id):
                result = self.collection.delete_one({"_id": ObjectId(record_id)})
                return result.deleted_count > 0
            return False
        except Exception:
            return False
    
    def delete_one(self, query: Dict[str, Any]) -> bool:
        """
        删除单个记录
        
        Args:
            query: 查询条件
            
        Returns:
            bool: 是否删除成功
        """
        result = self.collection.delete_one(query)
        return result.deleted_count > 0
    
    def delete_many(self, query: Dict[str, Any]) -> int:
        """
        删除多个记录
        
        Args:
            query: 查询条件
            
        Returns:
            int: 删除的记录数量
        """
        result = self.collection.delete_many(query)
        return result.deleted_count
    
    def count(self, query: Dict[str, Any] = None) -> int:
        """
        统计记录数量
        
        Args:
            query: 查询条件
            
        Returns:
            int: 记录数量
        """
        if query is None:
            query = {}
        return self.collection.count_documents(query)
    
    def exists(self, query: Dict[str, Any]) -> bool:
        """
        检查记录是否存在
        
        Args:
            query: 查询条件
            
        Returns:
            bool: 是否存在
        """
        return self.collection.count_documents(query, limit=1) > 0